package com.jianggy.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.jianggy.annotation.test.test1.Test3;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

/**
 * @author 江广友
 * @time 2018年5月4日 下午6:38:46
 * @description
 */
public class BeanContext implements BeanFactory {
	private static final Logger LOGGER = LogManager.getLogger(BeanContext.class.getName());
	private static final Map<String, Object> instanceMap = new HashMap<>();

	/**
	 * 初始化方法，将会扫描指定包中的所有类文件，并实例化
	 * @time 2018年5月4日 下午6:38:46
	 * TODO
	 */
	@Override
	public void init(String packageName) {
		PackageScanner scanner = new PackageScannerImp();
		try {
			List<String> list = scanner.doScan(packageName);
			for (Iterator iterator = list.iterator(); iterator.hasNext();) {
				String className = (String) iterator.next();
				Class clazz = Class.forName(className);
				Annotation beanAnnotation = clazz.getAnnotation(Bean.class);
				// 判断是否包含Bean注解，如果包含，实例化该类
				if (beanAnnotation != null) {
					Object object = clazz.newInstance();
					LOGGER.info("实例化类：" + className);
					instanceMap.put(className, object);
				}
			}
			// 注入
			inject();

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * @time 2018年5月4日 下午6:38:46
	 * TODO
	 */
	@Override
	public <T> T getBean(String beanName, Class<T> clazz) {
		return (T) instanceMap.get(beanName);
	}

	private void inject() {
		Set<Entry<String, Object>> entries = instanceMap.entrySet();
		for (Iterator<Entry<String, Object>> iterator = entries.iterator(); iterator.hasNext();) {
			Entry<String, Object> entry = iterator.next();
			Object object = entry.getValue();
			Field[] fields = object.getClass().getDeclaredFields();
			try {
				for (Field field : fields) {
					if (field.getDeclaredAnnotation(Resource.class) != null) {
						field.setAccessible(true);
						// 获取字段类型
						Class fieldClass = field.getType();
						// 如果是采用接口定义的变量
						if (fieldClass.isInterface()) {
							LOGGER.info("目前不支持使用接口定义变量");
						} else {// 使用类定义的变量
							LOGGER.info("开始注入" + entry.getKey() + "类的" + field.getName() + "字段");
							Object value = instanceMap.get(fieldClass.getName());
							if (value != null) {
								field.set(object, value);
							} else {
								throw new ClassNotFoundException();
							}
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		BeanFactory bFactory = new BeanContext();
		bFactory.init("com.jianggy.annotation");
		Test3 test3 = bFactory.getBean("com.jianggy.annotation.test.test1.Test3", Test3.class);
		test3.test();
	}
}
